package picol.view;

import java.awt.Color;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.io.FileNotFoundException;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import picol.controller.Controler;
import picol.view.component.IconButton;
import picol.view.component.MemoryFrame;
import picol.view.component.PanelEditor;
import picol.view.exception.SaveException;
import picol.view.utility.PCommand;
import picol.view.utility.PicolFileChooser;

/**
 *
 * @author Aurélien Marcel - Julien Sanderson
 */
public class ViewImp extends ViewAbs {

    private PanelEditor panelEditor;
    private JPanel panelButton;
    private JPanel panelOutput;
    private IconButton runButton;
    private IconButton debugButton;
    private IconButton nextButton;
    private IconButton stopButton;
    private JTextArea textOutput;
    private MenuBar menuBar;
    private Menu picolMenu;
    private Menu fileMenu;
    private MenuItem aboutItem;
    private MenuItem openFileItem;
    private MenuItem saveFileItem;
    private MenuItem newFileItem;
    private MenuItem saveAsFileItem;
    private PicolFileChooser fileChooser;
    private String currentProjectPath;
    private static final String IMAGE_PACKAGE_PATH = "/picol/view/images/";
    private MemoryFrame memoryFrame;

    public ViewImp() {
        super("PicoL");
    }

    @Override
    protected void _init() {

        this.frame_width = 900;
        this.frame_height = 600;

        this.memoryFrame = new MemoryFrame(this.frame_width);
        this.initMenuBar();
        //File chooser
        this.fileChooser = new PicolFileChooser();

        //Bouton
        this.runButton = new IconButton(IMAGE_PACKAGE_PATH + "Run.png");
        this.debugButton = new IconButton(IMAGE_PACKAGE_PATH + "Debug.png");
        this.nextButton = new IconButton(IMAGE_PACKAGE_PATH + "Next.png");
        this.stopButton = new IconButton(IMAGE_PACKAGE_PATH + "Stop.png");

        this.setDebugMode(false);

        this.panelButton = new JPanel();
        //this.panelButton.add(pane);

        this.panelButton.add(runButton);
        this.panelButton.add(debugButton);
        this.panelButton.add(nextButton);
        this.panelButton.add(stopButton);

        this.panelEditor = new PanelEditor();

        //Panel Ouput
        this.panelOutput = new JPanel();

        this.textOutput = new JTextArea(10, 70);

        this.textOutput.setBackground(Color.BLACK);
        this.textOutput.setForeground(Color.WHITE);

        JScrollPane scrollOutput = new JScrollPane(this.textOutput);
        this.addComponent(scrollOutput, 0, 0, this.panelOutput);
        this.addComponent(this.panelButton, 0, 0);
        this.addComponent(this.panelEditor, 0, 1);
        this.addComponent(this.panelOutput, 0, 2);

        this.setShortcut();

    }

    public void setDebugMode(boolean mode) {
        if (mode) {
            this.runButton.setEnabled(false);
            this.debugButton.setEnabled(false);
            this.nextButton.setEnabled(true);
            this.stopButton.setEnabled(true);
        } else {
            this.runButton.setEnabled(true);
            this.debugButton.setEnabled(true);
            this.nextButton.setEnabled(false);
            this.stopButton.setEnabled(false);
        }
    }

	/**
	 * Initialisation de la barre de menu
	 */
	private void initMenuBar() {
		//Menu bar
		this.menuBar = new MenuBar();
		this.picolMenu = new Menu("PicoL");
		this.fileMenu = new Menu("File");

        this.aboutItem = new MenuItem("About PicoL");
        this.openFileItem = new MenuItem("Open...");
        this.newFileItem = new MenuItem("New");
        this.saveFileItem = new MenuItem("Save");
        this.saveAsFileItem = new MenuItem("Save As...");

        this.picolMenu.add(aboutItem);
        this.fileMenu.add(newFileItem);
        this.fileMenu.add(saveFileItem);
        this.fileMenu.add(saveAsFileItem);
        this.fileMenu.add(openFileItem);

        this.menuBar.add(picolMenu);
        this.menuBar.add(fileMenu);

        this.setMenuBar(menuBar);
    }

	/**
	 * Initialisation des raccourcis
	 */
	private void setShortcut() {

        this.openFileItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_O, false));
        this.newFileItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_N, false));
        this.saveFileItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_S, false));
    }

	/**
	 * Souscription des composants interractifs
	 * @param _controler
	 */
	public void subscription(Controler _controler) {
		//Header Button
		this.runButton.addActionListener(_controler);
		this.debugButton.addActionListener(_controler);
		this.nextButton.addActionListener(_controler);
		this.stopButton.addActionListener(_controler);

        //Menu bar
        this.saveFileItem.addActionListener(_controler);
        this.saveAsFileItem.addActionListener(_controler);
        this.openFileItem.addActionListener(_controler);
        this.newFileItem.addActionListener(_controler);

        //Components
        this.panelEditor.subscription(_controler);
    }

	/**
	 * definition des commandes d'ecoute
	 */
	public void listening() {
		//button
		this.runButton.setActionCommand(PCommand.ACTION_RUN);
		this.debugButton.setActionCommand(PCommand.ACTION_DEBUG);
		this.nextButton.setActionCommand(PCommand.ACTION_NEXT);
		this.stopButton.setActionCommand(PCommand.ACTION_STOP);

        //Item
        this.saveFileItem.setActionCommand(PCommand.ACTION_SAVE);
        this.openFileItem.setActionCommand(PCommand.ACTION_OPEN);
        this.newFileItem.setActionCommand(PCommand.ACTION_NEW);
        this.saveAsFileItem.setActionCommand(PCommand.ACTION_SAVEAS);

    }

	/**
	 * recuperation du nombre de lignes contenues dans l'editeur
	 * @return
	 */
	public int getLineCount() {
		return this.panelEditor.getLineCount();
	}

	/**
	 * Retourne le compteur de lignes
	 * @return
	 */
	public int getCounterList() {
		return this.panelEditor.getCounterList();
	}

	/**
	 * Mise a jour du compteur de liste
	 * @param _count
	 */
	public void setCounterList(int _count) {
		this.panelEditor.setCounterList(_count);
	}

	/**
	 * Mise a jour du nombre de lignes
	 */
	public void setLineCount() {
		this.panelEditor.setLineCount();
	}

    /**
     * Methode pour recuperer le code contenu dans textAreaCode
     * @return a VirtualMachineController le code contenu dans textAreaCode
     */
    public String getCode() {
        return this.panelEditor.getText();
    }

    /**
     * Sauvegarde du code courant dans un fichier
     * @throws SaveException
     */
    public boolean saveFile() throws SaveException {
        if (this.currentProjectPath == null) {
            this.currentProjectPath = this.fileChooser.saveFileAs(this.panelEditor.getText());
            if (this.currentProjectPath != null) {
                return true;
            }
        } else {
            this.fileChooser.saveFile(this.currentProjectPath, this.panelEditor.getText());
            return true;
        }
        return false;
    }

    /**
     * Sauvegarde du code courant dans un fichier
     * @throws SaveException
     */
    public boolean saveAsFile() throws SaveException {
        this.currentProjectPath = this.fileChooser.saveFileAs(this.panelEditor.getText());
        if (this.currentProjectPath != null) {
            return true;
        }
        return true;
    }

    /**
     * Permet de choisir un fichier, et d'afficher son contenu a l'ecran
     * @throws FileNotFoundException
     */
    public void openFile() throws FileNotFoundException {
        this.currentProjectPath = this.fileChooser.selectFile();
        if (this.currentProjectPath != null) {
            this.panelEditor.setText(this.fileChooser.openFile(this.currentProjectPath));
        }
    }

	/**
	 * recuperation du chemin vers le fichier
	 * @return
	 */
	public String getProjectPath() {
		return this.currentProjectPath;
	}

	/**
	 * ajout de texte dans la console
	 * @param _string
	 */
	public void appendOutput(String _string) {
		this.textOutput.append(_string + "\n");
	}

	/**
	 * ecriture dans la console sans effacer
	 * @param _string
	 */
	public void writeOutput(String _string) {
		this.textOutput.append(_string);
	}

	/**
	 * ecriture dans la console avec effacement
	 * @param _string
	 */
	public void setOutput(String _string) {
		this.textOutput.setText(_string + "\n");
	}

	/**
	 * recuperation de la ligne selectionnee
	 * @return
	 */
	public int getClickedLine() {
		return this.panelEditor.getLineClicked();
	}

	/**
	 * modification de la ligne cliquee
	 * @param line
	 */
	public void setClickedLine(int line) {
		this.panelEditor.setClickedLine(line);
	}

	/**
	 * recuperation de la valeur saisie lors d'un read
	 * @return
	 */
	public int getScanValue() {
		int result = 0;
		boolean test = false;
		while (!test) {
			try {
				result = Integer.parseInt(JOptionPane.showInputDialog("Enter value :"));
				test = true;
			} catch (Exception e) {
				test = false;
			}
		}
		return result;
	}

	/**
	 * Vidage de la table des variables
	 * @param varList
	 */
	public void refreshMemory(String varList) {
		this.memoryFrame.setMemoryList(varList);
	}

	/**
	 * Nouveau Fichier
	 */
	public void newFile() {
		this.panelEditor.setText("");
		this.currentProjectPath = null;
	}
}
